package com.appspot.moviesessions.provider;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.content.ContentValues;

import com.appspot.moviesessions.EventPublisher;

public class XMLSessionDataHandler implements SessionDataHandler {

	private static final int DEFAULT_POSTER_SIZE = 150;
	private EventPublisher eventPublisher;
	private ContentValuesFactory contentValuesFactory;
	private PosterCache posterCache;
	private static final String POSTER_RESIZE_URL = "%s=s%s";

	public XMLSessionDataHandler(EventPublisher eventPublisher,
			ContentValuesFactory contentValuesFactory, PosterCache posterCache) {
		this.eventPublisher = eventPublisher;
		this.contentValuesFactory = contentValuesFactory;
		this.posterCache = posterCache;
	}

	@Override
	public void handle(InputStream stream) {
		try {
			XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
			factory.setNamespaceAware(false);
			XmlPullParser xpp = factory.newPullParser();
			xpp.setInput(new InputStreamReader(stream));
			int eventType = xpp.getEventType();
			/*
			 * I don't want to create too many objects so I'll reuse the bean
			 * for each matched movie.
			 */
			ContentValues values = contentValuesFactory.create();
			while (eventType != XmlPullParser.END_DOCUMENT) {
				if (eventType == XmlPullParser.START_TAG) {
					values.clear();
					if ("movie".equalsIgnoreCase(xpp.getName())) {
						// found movie tag.

						Long id = Long.valueOf(xpp
								.getAttributeValue(null, "id"));
						values.put(MovieSession.Movie._ID, id);
						values.put(MovieSession.Movie.NAME,
								xpp.getAttributeValue(null, "name"));
						String posterUri = String.format(POSTER_RESIZE_URL,
								xpp.getAttributeValue(null, "poster"),
								DEFAULT_POSTER_SIZE);
						values.put(MovieSession.Movie.POSTER_URI,
								posterCache.cache(id, posterUri));
						eventPublisher.publish(DataFoundEvent
								.movieDataFoundEvent(values));
					} else if ("location".equalsIgnoreCase(xpp.getName())) {
						Long id = Long.valueOf(xpp
								.getAttributeValue(null, "id"));
						values.put(MovieSession.Location._ID, id);
						values.put(MovieSession.Location.NAME,
								xpp.getAttributeValue(null, "name"));
						eventPublisher.publish(DataFoundEvent
								.locationDataFoundEvent(values));
					} else if ("session".equalsIgnoreCase(xpp.getName())) {
						values.put(MovieSession.Session.LOCATION, Long
								.valueOf(xpp
										.getAttributeValue(null, "location")));
						values.put(MovieSession.Session.MOVIE, Long.valueOf(xpp
								.getAttributeValue(null, "movie")));
						values.put(MovieSession.Session.TIME, Long.valueOf(xpp
								.getAttributeValue(null, "epochTime")));
						eventPublisher.publish(DataFoundEvent
								.sessionDataFoundEvent(values));
					}

				}
				eventType = xpp.next();
			}
			eventPublisher.publish(DataRefreshedEvent.INSTANCE);

		} catch (XmlPullParserException e) {
			throw new RuntimeException(e);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
